/*
******************************************************************************************************* 
**  Copyright (C) 2019, 苏州检易生物科技有限公司 
**  All rights reserved. 
** 
**  FileName:       	tube.h
**  Description:	
**  Author:        	 
**  Version				v0.1
**  Date:           	2019-09-06
**	Function List： 
**  History:         
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*                                              	防止重复包含
*********************************************************************************************************
*/

#ifndef _TUBE_H_
#define _TUBE_H_
/*
*********************************************************************************************************
*                                              	调试开关
*********************************************************************************************************
*/



/*
*********************************************************************************************************
*                                              	头文件
*********************************************************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "stm32h7xx_hal.h"
#include "supply.h"
#include "reagent.h"
#include "reagent_ab.h"
#include "sample.h"
#include "schedule_period.h"
#include <rtthread.h>
/*
*********************************************************************************************************
*                                              	宏定义
*********************************************************************************************************
*/
#define TUBE_BSAE_VOLUME	100
/*对于稀释的杯子 稀释倍数大于50的吸样量为5ul 否则为10ul*/
#define DILLUTE_SAMPLE_UL(dilute_ratio)	( (dilute_ratio > 50)? 5:10)

#if PRODUCT_NAME_IVD_400 | PRODUCT_NAME_IVD_SAMPLE
#define	TI_POOL_SIZE			(128)
#elif PRODUCT_NAME_DESKTOP_200 | PRODUCT_NAME_IVD_200
#define	TI_POOL_SIZE			(150)
#else
#define	TI_POOL_SIZE			(100)
#endif

//#if PRODUCT_NAME_DESKTOP_200 | PRODUCT_NAME_IVD_SAMPLE | PRODUCT_NAME_IVD_DEBUG
//#define REACTION_GRID_NUM	20
//#define TUBE_TOTAL_REACTION_DISK_CIRCLE	(REACTION_GRID_NUM*2)
//#define CLEAN_DISK_GRID_NUM		12
//#elif PRODUCT_NAME_IVD_400
//#define REACTION_GRID_NUM	45
//#define TUBE_TOTAL_REACTION_DISK_CIRCLE	(REACTION_GRID_NUM*2)
//#define CLEAN_DISK_GRID_NUM		20
//#elif PRODUCT_NAME_IVD_200
//#define REACTION_GRID_NUM	32
//#define TUBE_TOTAL_REACTION_DISK_CIRCLE	(REACTION_GRID_NUM*2)
//#define CLEAN_DISK_GRID_NUM		12
//#elif PRODUCT_NAME_IVD_900
//#define REACTION_GRID_NUM	50
//#define TUBE_TOTAL_REACTION_DISK_CIRCLE	(REACTION_GRID_NUM*4)
//#define CLEAN_DISK_GRID_NUM		40
//#endif

/*
*********************************************************************************************************
*                                              枚举和结构体类型定义
*********************************************************************************************************
*/

typedef enum{
	TUBE_APPLYIED = 0,/*已经申请 还未发送到下位机*/
	TUBE_ACCEPT 	= 1,/*在待测链表中*/
	TUBE_TESTING 	= 2,/*已经吸样完成*/
	TUBE_REACTION = 3,/*反应中*/
	TUBE_SUCCESS	= 4,/*正常测试完成*/
	TUBE_FAILED		= 5,//因为各种原因挂了 省略部分操作但最后要丢杯
}tube_status_t;


typedef enum{
	TUBE_ERR_NONE = 0,
	TUBE_ERR_DILUTE,
	TUBE_ERR_TUBE = 2,
	TUBE_ERR_REAGENT = 3,
	TUBE_ERR_BLOCK = 4,
	TUBE_ERR_SAMPLE_DELAY = 5,
	TUBE_ERR_UNEXIST = 6,
}tube_err_t;
#if PRODUCT_NAME_IVD_900
typedef enum{
	REACTION_OUTSIDE = 0,
	REACTION_SECOND,
	REACTION_THIRD,
	REACTION_INSIDE
}rnd_pos_t;
#else
typedef enum{
	REACTION_OUTSIDE,
	REACTION_INSIDE
}rnd_pos_t;
#endif
#pragma pack(1)
typedef struct TUBE_T{
	rnd_pos_t				rnd_pos;
//	tube_status_t		status;								//状态
//	tube_err_t 			err_code;
	uint32_t				period;								//该杯生成的时候的周期数
	uint16_t				sample_ul;						/*样本液量*/
	uint16_t				dilute_sample_ul;			/*稀释样本量*/
	uint16_t				dilute_ul;								/*稀释液的量*/
	uint8_t 				alkali;
	uint16_t				volume;								/*杯内的液量*/
	reagent_info_t*		p_reagent;
	reagent_info_t*		p_dilute;
	
	uint16_t  test_type;
	uint8_t  	sample_id[SAMPLE_ID_LEN];
	
	uint8_t		reagent_id[REAGENT_ID_LEN];
	uint8_t 	reagent_batch[REAGENT_BATCH_LEN];
	uint8_t		reagent_bottle[REAGENT_BOTTLE_LEN];
	
	uint32_t	base;
	uint32_t	flash;							//测试结果发光值
	
	uint8_t		tube_status;
	uint16_t	tube_err;
	
	uint8_t		method;
	struct TUBE_T*							tube_next;
}tube_t;

typedef struct{
	uint16_t  test_type;
	uint8_t  	sample_id[SAMPLE_ID_LEN];
	
	uint8_t		reagent_id[REAGENT_ID_LEN];
	uint8_t 	reagent_batch[REAGENT_BATCH_LEN];
	uint8_t		reagent_bottle[REAGENT_BOTTLE_LEN];

	uint32_t	base;
	uint32_t	flash;
	
	uint8_t		tube_status;
	uint16_t	tube_err;
	
	uint16_t	backup_checksum;
}tube_backup_t;
#pragma pack()

typedef struct tube_list{
	uint8_t 		cur_size;
	uint8_t			max_size;
	struct 			rt_mempool	rt_mem;
	tube_t*			head;
}tube_list_t;


typedef enum{
	UPLOAD_TUBE_SAMPLE,
	UPLOAD_TUBE_REACTION1,
	UPLOAD_TUBE_REACTION2,
	UPLOAD_TUBE_ERROR,
	UPLOAD_TUBE_IDLE,
}upload_tube_status_t;

#pragma pack(1)
typedef struct{
	uint8_t		reagent_id[REAGENT_ID_LEN];
	uint8_t  	sample_id[SAMPLE_ID_LEN];
	uint16_t		rnd_pos;
	upload_tube_status_t status;
	uint8_t 	reagent_batch[REAGENT_BATCH_LEN];
	uint8_t		reagent_bottle[REAGENT_BOTTLE_LEN];
}rnd_status_upload_t;
typedef struct{
	uint16_t  test_type;
	uint8_t  	sample_id[SAMPLE_ID_LEN];
	uint8_t		tube_status;
	uint16_t	tube_err;
}tube_status_upld_t;
#pragma pack()
/*
*********************************************************************************************************
*                                              	全局变量声明
*********************************************************************************************************
*/
//extern tube_list_t m_tube_list;
/*
*********************************************************************************************************
*                                              	函数声明
*********************************************************************************************************
*/
tube_err_t 	tube_init(void);

tube_t* tube_malloc(uint32_t period);

tube_err_t tube_add_reagent(tube_t * p_tube,reagent_info_t* p_reagent);

tube_err_t tube_add_sample(tube_t * p_tube,sample_info_t* p_sample);

tube_err_t tube_add_tube(tube_t * p_tube,tube_t * p_dilute);

tube_err_t tube_add_dilute(tube_t * p_tube,reagent_info_t* p_reagent);

tube_err_t tube_failed(tube_t * p_tube,tube_err_t err_code);

tube_err_t tube_free(tube_t* p_tube);

tube_t* tube_get(uint32_t cur_period,uint32_t period);

tube_t* tube_get_by_sid(uint8_t* sample_id);

tube_err_t tube_reload(uint32_t cur_period,tube_t* p_tube);

tube_t* tube_between(uint32_t cur_period,uint8_t start,uint8_t end);

tube_err_t tube_upld(tube_t*);

void tube_status_change(tube_t *p_tube,tube_status_t status,tube_err_t err);
void sample_failed(sample_node_t* p_sample,tube_err_t err);
void tube_save_local(uint8_t * buff,uint16_t size);

//uint32_t tube_ul(tube_t* p_tube,int32_t add_ul);
#endif
